<template>
  <div style="position: relative">
    <div class="spin" v-if="spin">
      <a-spin></a-spin>
    </div>
    <a-card>
      <div>
        <a-form layout="horizontal">
          <div>
            <a-row >
              <a-col :md="6" :sm="24" >
                <a-form-item label="选择园区" :labelCol="{span: 5}" :wrapperCol="{span: 18, offset: 1}">
                  <a-select v-model="query.farmName" placeholder="请选择园区" @change="farmChange">
                    <a-select-option
                        v-for="(item, index) in farmList"
                        :key="index" :value="item.FarmId">
                      {{item.FarmName}}
                    </a-select-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :md="6" :sm="24" >
                <a-form-item label="选择地块" :labelCol="{span: 5}" :wrapperCol="{span: 18, offset: 1}">
                  <a-select v-model="query.greenHouseName" placeholder="请选择地块" @change="houseChange">
                    <a-select-option
                        v-for="(item, index) in greenHouseList"
                        :key="index" :value="item.GreenHouseId">
                      {{item.GreenHouseName}}
                    </a-select-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :md="6" :sm="24" >
                <a-form-item label="选择设备" :labelCol="{span: 5}" :wrapperCol="{span: 18, offset: 1}">
                  <a-select v-model="query.devName" placeholder="请选择设备" @change="devChange">
                    <a-select-option
                        v-for="(item, index) in devList"
                        :key="index" :value="item.DevId">
                      {{item.DevName + '-' + item.DevCode}}
                    </a-select-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :md="6" :sm="24">
                <div style="margin: 3px 0 0 8px;">
                  <a-button type="primary" @click="search">查询</a-button>
                  <a-button style="margin-left: 8px" @click="dataInit">重置</a-button>
                </div>
              </a-col>
            </a-row>
          </div>
        </a-form>
      </div>
      <div class="file" v-if="downLoadQuery.DevCode != ''">
        <div class="file-title">历史数据下载：</div>
        <div class="file-date">
          <a-range-picker separator="-" :value="downLoadDate" @change="downLoadDateRangeChange">
            <a-icon slot="suffixIcon" type="calendar" />
          </a-range-picker>
        </div>
        <div class="file-btn">
          <a-button @click="downLoadFile"><a-icon type="download"/>下载</a-button>
        </div>
      </div>
      <div class="card" v-if="iccFlag">
        <div class="card-info">
          <div class="info-tag">
            <a-icon type="idcard" /> 卡号 : {{iccId}}
          </div>
        </div>
        <div class="cart-btn">
          <a-button @click="cardSearch" size="small" type="danger">流量查询</a-button>
        </div>
      </div>
      <div>
        <a-list class="main-list" :grid="{ gutter: 16, xs: 1, sm: 2, md: 3, lg: 3, xl: 4, xxl: 4 }" :data-source="devData.kvList">
          <a-list-item slot="renderItem" slot-scope="item, index" class="item-list-m">
            <a-card :title="item.DisplayName">
              <a slot="extra" v-if="item.DisplayType == 'label'"><a-icon type="line-chart" style="font-size: 18px" @click="showChart(item.FieldName)"/></a>
              <div class="field-main">
                <div class="field-name">字段名</div>
                <div class="field-value"><a>[ {{item.FieldName}} ]</a></div>
              </div>
              <div class="field-main m-t-10">
                <div class="field-name">当前状态</div>
                <div class="field-value" v-if="item.DisplayType == 'button'" :class="`status_${item.Value}`">{{buttonFieldName(item.Value, item.ValueMap)}}</div>
                <div class="field-value" v-if="item.DisplayType == 'label' || item.DisplayType == 'tab'">{{itemValue(item)}}</div>
                <div class="field-value" v-if="item.DisplayType == 'time'">{{timeFormat(item.Value)}}</div>
              </div>
              <!--  下载选中  -->
              <div class="field-main m-t-10" v-if="item.DisplayType == 'label'">
                <div class="field-name">下载选中</div>
                <div class="field-main">
                  <a-checkbox @change="fun => fieldCheckBoxChange(item.FieldName)">
                  </a-checkbox>
                </div>
              </div>
              <div class="field-main m-t-10" v-if="item.DisplayType == 'button'">
                <div class="field-name">操作</div>
                <div class="field-btns">
                  <div class="m-btn" :class="`btn_${v.Value}`"
                       v-for="(v, k) in item.ValueMap" :key="k"
                       v-text="v.DisplayValue"
                       @click="setProperty(item, index, v, 'button')">
                  </div>
                </div>
              </div>
              <div class="field-main m-t-10" v-if="item.DisplayType == 'tab'">
                <div class="field-name">目标值</div>
                <div class="field-tab">
                  <div class="tab-input">
                    <a-input-search style="width: 150px" :placeholder="item.Value" size="small" @search="(e, enent) => setProperty(item, index, e, 'tab')">
                      <a-button slot="enterButton">
                        提交
                      </a-button>
                    </a-input-search>
                  </div>
                </div>
              </div>
              <div class="field-main m-t-10" v-if="item.DisplayType == 'time'">
                <div class="field-name">目标值</div>
                <div class="field-tab">
                  <a-time-picker class="time-p" format="HH:mm" size="small" @change="timeChange"/>
                  <a-button slot="enterButton" size="small" @click="setProperty(item, index, '', 'time')">
                    确定
                  </a-button>
                </div>
              </div>
            </a-card>
          </a-list-item>
        </a-list>
      </div>
      <!-- 操作确认框 -->
      <a-modal
          title="提示"
          :centered="true"
          :visible="visible"
          :confirm-loading="confirmFlag"
          @ok="() => opConfirm(timeValue)"
          @cancel="opCancel"
      >
        <p v-html="modalContent"></p>
      </a-modal>
      <!-- 流量 -->
      <a-modal v-model="gprsFlag" :title="devData.devCode + '流量查询'" :footer="null">
        <p v-text="`卡状态: ${gprsInfo.WorkingCondition}`"></p>
        <p v-text="`到期日期: ${gprsInfo.DueDate}`"></p>
        <p v-text="`总流量: ${gprsInfo.TotalGprs}M`"></p>
        <p v-text="`剩余流量: ${gprsInfo.RemainGprs}M`"></p>
      </a-modal>
      <!-- 传感器曲线 -->
      <a-modal v-model="chartFlag" title="传感器曲线" :footer="null" :width="960" :centered="true" @cancel="chartModalClose">
        <div class="chart">
          <div class="chart-top">
            <a-form-model>
              <a-form-model-item label="选择日期" :label-col="{ span: 3 }" :wrapper-col="{ span: 14 }" class="item">
                <a-range-picker separator="-" :value="licenseDate" @change="dateRangeChange">
                  <a-icon slot="suffixIcon" type="calendar" />
                </a-range-picker>
              </a-form-model-item>
              <a-form-model-item label="加载条数" :label-col="{ span: 3 }" :wrapper-col="{ span: 14 }" class="item">
                <a-select v-model="chartQuery.PageSize" style="width: 100px">
                  <a-select-option v-for="(item, index) in pageSizeMap" :key="index" :value="item">
                    {{item}}
                  </a-select-option>
                </a-select>
              </a-form-model-item>
              <a-form-item :wrapper-col="{ span: 14, offset: 3}" class="item">
                <a-button type="primary" @click="chartConfirm">确定</a-button>
              </a-form-item>
            </a-form-model>
          </div>
          <div class="chart-main" id="chart">
            <div class="chart-content" v-if="!chartDataIsEmpty">
              <v-chart :force-fit="true" :height="height" :data="chartDataObj" :padding="['auto']">
                <v-tooltip />
                <v-axis/>
                <v-smooth-area position="x*y" />
              </v-chart>
            </div>
            <div class="chart-empty" v-else>
              <a-empty />
            </div>
          </div>
          <div class="chart-page">
            <a-button type="dashed" @click="toPage('pre')">上翻</a-button>
            <a-button type="dashed" style="margin-left: 10px" @click="toPage('next')">下翻</a-button>
          </div>
        </div>
      </a-modal>
    </a-card>
  </div>
</template>

<script>
  import moment from 'moment'
  import socket from '@/mixins/socket'
  import { list as farmList } from '@/services/farm'
  import { list as greenHouseList } from '@/services/greenhouse'
  import { list as devList, setProperty, getProperty, getIcc, cardGprs } from '@/services/dev'
  import {filterArray, numToTime} from '@/utils/util'
  import { curByPage, downLoadFile, checkFile } from '@/services/curve'

  const tooltip = [
    'x*y',
    (x, y) => ({
      name: x,
      value: y
    })
  ]

  const scale = [{
    dataKey: 'x',
    min: 0,
    max: 2,
    title: ''
  }, {
    dataKey: 'y',
    title: '时间',
    min: 0,
    max: 22
  }]
  export default {
    name: "DevController",
    data() {
      return {
        spin: false,
        visible: false,
        modalContent: '',
        confirmFlag: false,
        farmList: [],
        greenHouseList: [],
        devList: [],
        index: null, // dev索引
        data: {}, //修改属性
        timeValue: '', //修改时间专用
        query: {
          farmId: undefined,
          farmName: undefined,
          greenHouseId: undefined,
          greenHouseName: undefined,
          devId: undefined,
          devName: undefined
        },
        devData: {
          connTime: '',
          devCode: '',
          kvList: []
        },
        iccFlag: false,
        iccId: '',
        gprsFlag: false,
        gprsInfo:{},
        chartFlag: false,
        licenseDate: [],
        chartQuery: {
          BeginTime: '',
          EndTime: '',
          DevCode: '',
          FieldName: '',
          PageNum: 1,
          PageSize: 10
        },
        pageSizeMap: [10, 20, 50],
        chartDataObj: [],
        chartCount: 0,
        chartDataIsEmpty: false,
        scale,
        tooltip,
        height: 350,
        downLoadQuery: { // 文件下载
          DevCode: '',
          FieldNames: [],
          BeginTime: '',
          EndTime: ''
        },
        downLoadDate: []
      }
    },
    mixins: [socket],
    computed: {
      buttonFieldName(value, map) {
        return (value, map) => {
          let obj = map.find(item => item.Value == value)
          return obj.DisplayValue
        }
      },
      itemValue(obj) {
        return obj => {
          if(obj.ValueMap.length != 0) {
            const map = obj.ValueMap.find(item => item.Value == obj.Value)
            return map.DisplayValue
          }
          return obj.Value + obj.Unit
        }
      },
      timeFormat(e) {
        return e => {
          return numToTime(e)
        }
      }
    },
    created() {
      this.getFarmList()
    },
    methods: {
      //下载选中处理
      fieldCheckBoxChange(e) {
        if(this.downLoadQuery.FieldNames.includes(e)) {
          const index = this.downLoadQuery.FieldNames.findIndex(item => item == e)
          this.downLoadQuery.FieldNames.splice(index, 1)
        } else {
          this.downLoadQuery.FieldNames.push(e)
        }
        console.log(this.downLoadQuery.FieldNames);
      },
      //确定下载
      downLoadFile() {
        if(this.downLoadQuery.BeginTime == '' || this.downLoadQuery.EndTime == '') {
          return this.$message.warning('请选择下载日期')
        }
        if(this.downLoadQuery.FieldNames.length == 0) {
          return this.$message.warning('未选中下载项')
        }
        downLoadFile(this.downLoadQuery).then(res => {
          if(res.Code == 0) {
            this.checkFileStatus(res.Data)
          }
        })
      },
      //检查文件是否生成
      checkFileStatus(e) {
        this.spin = true
        this.$message.info('导出中...')
        let timer = setInterval(() => {
          checkFile(e).then(res => {
            if(res != '') {
              clearInterval(timer)
              this.spin = false
              this.$message.success('导出成功')
              const aLink = document.createElement('a')
              var blob = new Blob([res], { type: 'application/csv' })
              aLink.href = URL.createObjectURL(blob)
              // 2.直接使用自定义文件名
              aLink.setAttribute('download', moment().format('YYYY-MM-DD HH:mm:ss')+'.csv') // 设置下载文件名称
              document.body.appendChild(aLink)
              aLink.click()
              document.body.removeChild(aLink);
            }
          })
        }, 500)
      },
      timeChange(m, e) {
        this.timeValue = e
      },
      async getFarmList() {
        let res = await farmList()
        this.farmList = res.Data
      },
      async getGreenHouseList() {
        let res = await greenHouseList(this.query.farmId)
        this.greenHouseList = res.Data
      },
      async getDevList() {
        let res = await devList(this.query.greenHouseId)
        this.devList = res.Data
      },
      opConfirm(timeValue) {
        this.confirmFlag = true
        setProperty(this.data).then(res => {
          if(res.Code == 0) {
            this.$message.success(res.Message)
            if(timeValue == '') this.devData.kvList[this.index].Value = this.data.Value
            else this.devData.kvList[this.index].Value = numToTime(this.data.Value)
          } else {
            this.$message.error(res.Message)
          }
        }).catch(err => {
          this.$message.error("参数设置失败")
          console.log(JSON.stringify(err))
        })

        this.confirmFlag = false
        this.visible = false
      },
      setProperty(obj, index, map, type='button') {
        if(type == 'button') {
          if(obj.Value == map.Value) {
            this.$message.error(`当前状态 ${map.DisplayValue}`)
            return
          }
          this.modalContent = `确定${map.DisplayValue} <span style="color: red">${obj.DisplayName}</span>?`
          this.data = {
            DevCode: this.devData.devCode,
            FieldName: obj.FieldName,
            Value: map.Value,
            ValueType: obj.ValueType
          }
        }
        if(type == 'tab') {
          let value = map
          if(obj.Value == value) {
            this.$message.error(`当前值为 ${value} 无需修改`)
            return
          }
          this.modalContent = `确定修改${obj.DisplayName}值为 <span style="color: red">${map}</span> ?`
          this.data = {
            DevCode: this.devData.devCode,
            FieldName: obj.FieldName,
            Value: value,
            ValueType: obj.ValueType
          }
        }
        if(type == 'time') {
          let value = this.timeValue
          if(obj.Value == value) {
            this.$message.error(`当前值为 ${value} 无需修改`)
            return
          }
          this.modalContent = `确定修改${obj.DisplayName}值为 <span style="color: red">${value}</span> ?`
          this.data = {
            DevCode: this.devData.devCode,
            FieldName: obj.FieldName,
            Value: value.replace(':', ''),
            ValueType: obj.ValueType
          }
        }
        this.visible = true
        this.index = index
      },
      opCancel() {
        this.$message.info("您取消了操作")
        this.visible = false
      },
      farmChange(e) {
        this.query.farmId = e
        this.queryInit(true)
        this.getGreenHouseList()
      },
      houseChange(e) {
        this.query.greenHouseId = e
        this.queryInit()
        this.getDevList()
      },
      devChange(e) {
        this.query.devId = e
      },
      search() {
        this.iccFlag = false
        this.downLoadQuery.FieldNames = []
        if(!this.query.devId) {
          this.$message.error('设备未选择')
          return
        }
        let devData = this.devList.find(item => item.DevId == this.query.devId)
        let {ConnTime, DevCode, KvList} = devData
        this.devData = {
          connTime: ConnTime,
          devCode: DevCode,
          kvList: []
        }
        this.downLoadQuery.DevCode = DevCode //下载devCode赋值
        getProperty(DevCode).then(res => {
          if(res.Code == 0) {
            const kvlist = filterArray(res.Data)
            this.devData.kvList = kvlist.filter(item => item.NotShow == false)
            // socket 订阅
            this.fieldNameArr = this.devData.kvList.map(item => {
              return item.FieldName
            })
            this.initWebSocket()
          } else {
            this.$message.error(res.Message)
          }
        }).catch(err => {
          console.log(err);
          this.$message.error('查询失败')
        })
        getIcc(DevCode, 'iccid').then(res => {
          if(res.Data.length != 0 && res.Data[0].Value !='') { //Value可能为空值
            this.iccFlag = true
            this.iccId = res.Data[0].Value
          }
        })
      },
      //查询iccid
      async cardSearch() {
        let res = await cardGprs(this.devData.devCode)
        this.gprsFlag = true
        this.gprsInfo = res.Data
      },
      showChart(e) {
        this.chartFlag = true
        this.chartDataIsEmpty = true
        this.chartQuery.DevCode = this.devData.devCode
        this.chartQuery.FieldName = e
      },
      //确定查询
      chartConfirm() {
        this.chartQuery.PageNum = 1 //从第一条显示
        this.chartDataObj = this.$options.data().chartDataObj
        this.showLine()
      },
      //显示曲线
      async showLine() {
        this.chartDataObj = []
        if(this.chartQuery.BeginTime == '') {
          this.$message.error("请选择开始时间")
          return
        }
        if(this.chartQuery.EndTime == '') {
          this.$message.error("请选择结束时间")
          return
        }
        let res = await curByPage(this.chartQuery)
        if(res.Code == 0) {
          if(res.Data.Result == null) {
            this.chartDataIsEmpty = true
                this.$message.warning("查询无数据")
            return
          }
          this.chartDataIsEmpty = false
          res.Data.Result.forEach(async item => {
            this.chartDataObj.unshift({
              x: moment(item.DataTime.replace("Z", "+08:00")).format("HH:mm"),
              y: item.Value
            })
          })
          this.chartCount = res.Data.Count
        } else {
          this.$message.error(res.Message)
        }
      },
      toPage(type) {
        if(type == 'pre') {
          if(this.chartQuery.PageNum == 1) {
            this.$message.warning("已经是首页了")
            return
          }
          this.chartQuery.PageNum -= 1
          this.showLine()
        }
        if(type == 'next') {
          const max = Math.ceil(this.chartCount/this.chartQuery.PageSize)
          if(this.chartQuery.PageNum == max) {
            this.$message.warning("已经是尾页了")
            return
          }
          this.chartQuery.PageNum += 1
          this.showLine()
        }
      },
      // 数据接收
      websocketonmessage(e){
        console.log(e.data);
        const data = JSON.parse(e.data)
        if(data.length !=0) {
          this.devData.kvList = data
        }
      },
      queryInit(type=false) {
        this.query.devName = undefined
        this.query.devId = undefined
        if(type) {
          this.query.greenHouseId = undefined
          this.query.greenHouseName = undefined
        }
      },
      dateRangeChange(dates, dateStrings) {
        this.licenseDate = dates;
        this.chartQuery.BeginTime = dateStrings[0]
        this.chartQuery.EndTime = dateStrings[1]
      },
      //下载日期
      downLoadDateRangeChange(dates, dateStrings) {
        this.downLoadDate = dates;
        this.downLoadQuery.BeginTime = dateStrings[0]
        this.downLoadQuery.EndTime = dateStrings[1]
      },
      dataInit() {
        // this.$options可以获取配置对象，配置对象的data函数执行，返回的响应式数据为空的
        Object.assign(this.$data, this.$options.data())
        this.getFarmList()
      },
      chartModalClose() {
        this.chartDataObj = this.$options.data().chartDataObj
        this.chartQuery = this.$options.data().chartQuery
        this.licenseDate = []
      }
    }
  }
</script>

<style scoped lang="less">
  .item-list-m {
    display: inline-block;
    float: none;
    vertical-align: top;
  }
  .top-header {
    color: #1890ff;
    background-color: #e6f7ff;
    border: 1px solid #91d5ff;
    padding: 10px;
  }
  .card {
    display: flex;
    align-items: center;
    .card-info {
      border: 1px dashed #dedede;
      padding: 3px 10px;
      border-radius: 3px;
      display: flex;
      justify-content: flex-start;
      color: #13c2c2;
      .info-tag {
      }

    }
    .cart-btn {
      margin: 0 0 0 10px;
    }
  }
  .file {
    padding: 0 10px;
    display: flex;
    align-items: center;
    .file-date {
      margin-left: 10px;
    }
    .file-btn {
      margin-left: 10px;
    }
  }
  .main-list {
    margin-top: 10px;
  }
  .field-main {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    align-items: center;
    .field-btns {
      flex: 1;
      display: flex;
      justify-content: flex-end;
      color: #fff;
      .m-btn {
        padding: 5px 10px;
        border-radius: 5px;
        margin-left: 5px;
        cursor: pointer;
      }
      .btn_1{
        background: #67c23a;
      }
      .btn_0 {
        background: #f56c6c;
      }
      .btn_2 {
        background: #e6a23c;
      }
    }
    .field-tab {
      flex: 1;
      display: flex;
      justify-content: flex-end;
      align-items: center;
      .time-p {
        margin-right: 5px;
      }
    }
  }
  .status_1{
    color: #67c23a;
  }
  .status_0 {
    color: #f56c6c;
  }
  .status_2 {
    color: #e6a23c;
  }
  .m-t-10 {
    margin-top: 10px;
  }
  .chart {
    .chart-top {
      border: 1px dashed #dedede;
      border-radius: 5px;
      padding: 10px 0 0 0;
      .item {
        margin-bottom: 10px;
      }
    }
    .chart-main {
      width: 100%;
      height: 350px;
      .chart-empty {
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
    .chart-page {
      display: flex;
      justify-content: center;
    }
  }
  .spin {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    z-index: 999;
    background: rgba(0,0,0,.2);
    display: flex;
    align-items: center;
    justify-content: center;
  }
</style>
